package main.kotlin

import java.lang.Math.abs

class Ble {



}
/**
    0x00  0x03  0xc3  0x01  0x00  0x61  0x1a  0x17  0x7c  0x00  0x06  0x00  0x16  0x04  0x5f  0x4a  0xed  0xa4  0x00  0x29
    0x01  0x02  0x00  0x43  0x00  0x30  0x02  0x00  0x78  0x00  0x35  0x01  0x68  0x00  0x41  0x01  0x02  0x00  0x20  0x01
    0x02  0x01
    0x00  0x02  0xc3  0x01  0x00  0x5f  0x4c  0x34  0x3d  0x00  0x03  0x00  0x16  0x04  0x62  0x2e  0xc2  0x68  0x00  0x20
    0x01  0x01  0x00  0x00  0x31  0x02  0x00  0x00

    0x00  0x01  0xb3  0x01  0x00  0x50  0x6c  0xb3  0x89  0x00  0x00  0x00  0x00  0x00

    0x00  0x02  0xb3  0x01  0x00  0x50  0x6c  0xb3  0x89  0x01  0x00  0x12  0x04  0x61  0x1f  0x25  0x05  0x00  0x22  0x02
    0x01  0x08  0x16  0x00  0x1f  0x02  0x00  0x00
 */
// 116 68 105  06:38
// L0  3-14  12:19
fun main(){
    init()
    var byteList = ArrayList<ByteArray>()
//    byteList.add(byteArrayOf(0x00,0x03,0xc3.toByte(),0x01,0x00,0x5f,0x4c,0x2a,0x8c.toByte(),0x00,0x06,0x00,0x16,0x04,0x5f,0x4c,0x2a,0x50,0x00,0x29))
//    byteList.add(byteArrayOf(0x01,0x02,0x00,0x44,0x00,0x30,0x02,0x00,0x74,0x00,0x35,0x01,0x69,0x00,0x41,0x01,0x02,0x00,0x20,0x01))
//    byteList.add(byteArrayOf(0x02,0x01))

//    byteList.add(byteArrayOf(0x00,0x02,0xc3.toByte(),0x01,0x00,0x5f,0x4c,0x34,         0x3d,         0x00,0x03,0x00,0x16,0x04,0x62,0x2e,0xc2.toByte(),0x68,0x00,0x20))
//    byteList.add(byteArrayOf(0x01,0x01,0x00,0x00,0x31,0x02,0x00,0x00))

    // 体脂秤  28.1    2021/8/23  17：46
    byteList.add(byteArrayOf(0x00,0x02,0xb3.toByte(),0x01,0x00,0x61,0x2c,0xa4.toByte(),0x05,0x01,0x00,0x12,0x04,0x61,0x23,0x6e,0xe8.toByte(),0x00,0x22,0x02))
    byteList.add(byteArrayOf(0x01,0x0a,0xfa.toByte(),0x00,0x1f,0x02,0x01,0x63 ))

    val result = dealResult(byteList)
    println(result.toString())
}

val keyMap = HashMap<Byte, String>()

fun init() {
    keyMap[0x12.toByte()] = "UTC"
    keyMap[0x15.toByte()] = "TimeZone"
    keyMap[0x16.toByte()] = "TimeStamp"
    keyMap[0x1f.toByte()] = "阻抗(单 位:Ω)"
    keyMap[0x20.toByte()] = "UserNumber"
    keyMap[0x22.toByte()] = "weight"
    keyMap[0x29.toByte()] = "BloodPressure1"
    keyMap[0x30.toByte()] = "BloodPressure2"
    keyMap[0x31.toByte()] = "BloodGlucose"
    keyMap[0x32.toByte()] = "BloodOxygen"
    keyMap[0x33.toByte()] = "ECG"
    keyMap[0x34.toByte()] = "nonECG"
    keyMap[0x35.toByte()] = "HeartBeat"
    keyMap[0x41.toByte()] = "BloodPressureUnit"
    keyMap[0x42.toByte()] = "BloodGlucoseUnit"
    keyMap[0x43.toByte()] = "BloodOxygenUnit"
    keyMap[0x45.toByte()] = "DIA"
    keyMap[0x51.toByte()] = "heartrate"
    keyMap[0x64.toByte()] = "SYS"

    keyMap[0xcc.toByte()] = "CRC-Check"
}

/**
 *  处理设备通过notify通道返回的数据
 */
fun dealResult(byteList: ArrayList<ByteArray>):Map<String, Any>{
    return getC3Data(byteList)
}

// 存储每个指令上一次接收的时间点，校验是否接收的帧不可用
private val timeMap = HashMap<Byte,Long>()

// 获取同步指令数据
private fun getC3Data(byteList: List<ByteArray>):Map<String, Int>{
    val map = HashMap<String, Int>()
    var bytes:ByteArray = byteList[0]
    map["CommandID"] = bytes[2].toUByte().toInt()
    map["Key"] = bytes[3].toUByte().toInt()
    map[keyMap[0x16.toByte()]?:"TimeStamp"] = getResultTimeStamp(bytes)

    for (tlvDatum in getTLVData(byteList,9)) {
        map[tlvDatum.key] = tlvDatum.value
    }
    return map
}

/**
 * 获取数据部分
 * 中国移动以0xFD和0x00作为两个TLV之间的分割符
 * startIndex：Data下标-1
 */
private fun getTLVData(byteList: List<ByteArray>, startIndex:Int):Map<String, Int>{
    val map = HashMap<String, Int>()
    var size = 0
    var index = 0
    for (bytes in byteList) {
        size+=bytes.size
    }
    size -= byteList.size
    // Data字段数据部分
    var dataArray = ByteArray(size)

    for (bytes in byteList) {
        System.arraycopy(bytes, 1, dataArray, index, bytes.size - 1)
        index += bytes.size - 1
    }
    index = startIndex
    while (++index<dataArray.size){
        when(dataArray[index]){
            0xFD.toByte() -> {
                continue
            }
            0x00.toByte() -> {
                continue
            }
            else->{
                // TODO length不定长处理
                val curDataSize = dataArray[index+1].toInt()
                var curDataArray = ByteArray(curDataSize)
                println("dataArray=${dataArray[index+2]}  curDataSize=${curDataSize}")
                System.arraycopy(dataArray,index+2,curDataArray,0,curDataSize)
                var value = 0
                // 单（多）字节数据
                for (i in 0 until curDataSize){
                    value += curDataArray[i].toUByte().toInt() shl (curDataSize-i-1)*8
                }
                map[keyMap[dataArray[index]]?:dataArray[index].toUByte().toString()] = value
                index+=curDataSize+1
            }
        }
    }
    return map
}

/**
 * 获取绑定结构的时间戳
 */
private fun getResultTimeStamp(bytes:ByteArray):Int{
    // 获取时间戳
    var timeStamp = 0
    for (i in 0..3){
        // 进行位运算要先转换为无符号数
        timeStamp += bytes[5+i].toUByte().toInt() shl (3-i)*8
    }

    val timeStampNow = (System.currentTimeMillis()/1000).toInt()
    // Ble设备时间戳错误时返回系统时间
    return if(kotlin.math.abs(timeStamp - timeStampNow) <10*1000) timeStamp else timeStampNow
}
